package me.flyray.bsin.gateway.service.impl;

import com.alipay.sofa.rpc.api.GenericService;
import com.alipay.sofa.rpc.config.ConsumerConfig;

import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Map;

import io.seata.saga.engine.StateMachineEngine;
import io.seata.saga.statelang.domain.ExecutionStatus;
import io.seata.saga.statelang.domain.StateMachineInstance;
import me.flyray.bsin.gateway.common.ApiResult;
import me.flyray.bsin.gateway.domain.BsinChoreographyServiceBiz;
import me.flyray.bsin.gateway.pojo.Parameter;
import me.flyray.bsin.gateway.service.BsinStateMachineServiceTaskProxy;

@Service
public class BsinStateMachineServiceTaskProxyImpl implements BsinStateMachineServiceTaskProxy {

    public static StateMachineEngine stateMachineEngine;
    public ConsumerConfig<GenericService> consumerConfig;

    //数组传参
    @Override
    public Object invoke(String serviceName, String serviceMethod, Object[] parameter) {

        ConsumerConfig<GenericService> consumerConfig = new ConsumerConfig<GenericService>()
                .setInterfaceId("me.flyray.bsin.facade.service." + serviceName)
                .setGeneric(true).setDirectUrl("bolt://127.0.0.1:12200");
        GenericService testService = consumerConfig.refer();

        String[] parameterType = new String[parameter.length];

        for (int i = 0; i < parameter.length; i++) {
            if (parameter[i].getClass().getName().equals("com.alibaba.fastjson.JSONObject")) {
                Map<String, Object> map = (Map) parameter[i];
                parameter[i] = map;
                parameterType[i] = "java.util.Map";
                continue;
            }
            parameterType[i] = parameter[i].getClass().getName();
            System.out.println(parameterType[i]);
        }

        Object result = testService.$invoke(serviceMethod, parameterType, parameter);
        System.out.println(result);
        return result;
    }


    //map传参
    @Override
    public Object execute(Map<String, Object> parameter) {
        String serviceName = (String) parameter.get("serviceName");
        String serviceMethod = (String) parameter.get("serviceMethod");
        Map<String, Object> param = (Map<String, Object>) parameter.get("param");

        if (consumerConfig == null) {
            consumerConfig = new ConsumerConfig<GenericService>();
        }
        consumerConfig.unRefer();
        consumerConfig.setInterfaceId("me.flyray.bsin.facade.service." + serviceName)
                .setGeneric(true).setDirectUrl("bolt://127.0.0.1:12200");
        GenericService testService = consumerConfig.refer();


        String[] parameterType = new String[param.size()];
        Object[] params = new Object[param.size()];

        int i = 0;
        for (Object paramKey : param.keySet()) {
            parameterType[i] = param.get(paramKey).getClass().getName();
            params[i] = param.get(paramKey);
            i++;
        }

        Object result = testService.$invoke(serviceMethod, parameterType, params);
        System.out.println(result);
        return result;
    }


    //对象入参
    @Override
    public Object execute(Parameter parameter) {

        ConsumerConfig<GenericService> consumerConfig = new ConsumerConfig<GenericService>()
                .setInterfaceId("me.flyray.bsin.facade.service." + parameter.getServiceName())
                .setGeneric(true).setDirectUrl("bolt://127.0.0.1:12200");
        GenericService testService = consumerConfig.refer();

        String[] parameterType = new String[parameter.getParam().size()];
        Object[] params = new Object[parameter.getParam().size()];
        int i = 0;
        for (String paramName : parameter.getParam().keySet()
        ) {
            parameterType[i] = parameter.getParam().get(paramName).getClass().getName();
            params[i] = parameter.getParam().get(paramName);
            i++;
        }

        Object result = testService.$invoke(parameter.getServiceMethod(), parameterType, params);
        System.out.println(result);
        return result;
    }


    /**
     * 编排服务调用
     */
    public ApiResult choreographyInvoke(BsinChoreographyServiceBiz choreographyServiceBiz, Map<String, Object> reqParam) {
        String stateMachineName = choreographyServiceBiz.getStateMachineName();
        String businessKey = String.valueOf(System.currentTimeMillis());
        reqParam.put("businessKey", businessKey);
        //sync test  同步
        StateMachineInstance inst = stateMachineEngine.startWithBusinessKey(stateMachineName, null,
                businessKey, reqParam);
        Assert.isTrue(ExecutionStatus.SU.equals(inst.getStatus()),
                "saga transaction execute failed. XID: " + inst.getId());
        System.out.println("saga transaction commit succeed. XID: " + inst.getId());
        return ApiResult.ok("saga transaction commit succeed. XID: " + inst.getId());
    }

}


